The Linux startup process is the process of Linux-operating system initialization. It is in many ways similar to the BSD and other Unix style boot processes, from which it derives.
Contents |
In Linux, the flow of control during a boot is from BIOS, to boot loader, to kernel. The kernel then starts the scheduler (to allow multi-tasking) and runs the first userland (i.e. outside kernel space) program Init (which sets up the user environment and allows user interaction and login), at which point the kernel goes idle unless called externally.
( A conventional computer operating system usually segregates virtual memory into kernel space and user space. Kernel space is strictly reserved for running the kernel, kernel extensions, and most device drivers. In contrast, user space is the memory area where all user mode applications work and this memory can be swapped out when necessary.
Similarly, the term userland refers to all application software that runs in user space.[1] Userland usually refers to the various programs and libraries that the operating system uses to interact with the kernel: software that performs input/output, manipulates file system objects, etc.
Each user space process normally runs in its own virtual memory space, and, unless explicitly requested, cannot access the memory of other processes. This is the basis for memory protection in today's mainstream operating systems, and a building block for privilege separation. Depending on the privileges, processes can request the kernel to map part of another process's memory space to its own, as is the case for debuggers. Programs can also request shared memory regions with other processes.
init (short for initialization) is a program for Unix-based computer operating systems that spawns all other processes. It runs as a daemon and typically has PID 1. The boot loader starts the kernel and the kernel starts init. If one were to delete init without a replacement, the system would encounter a kernel panic on the next reboot. )
In detail:
start_kernel()
.start_kernel()
then performs the majority of system setup (interrupts, the rest of memory management, device initialization, drivers, etc.) before spawning separately, the idle process and scheduler, and the Init process (which is executed in user space).( A computer processor is described as idle when it is not being used by any program.
Programs which make use of CPU Idle Time mean that they run at a low priority so as not to impact programs that run at normal priority. Many programs that use CPU idle time cause the CPU to always be 100% utilized, so that the time spent where the CPU would have been idle is instead spent performing useful computations. This generally causes the CPU to consume more power as most modern CPUs can enter power-save modes when they are idle. On modern processors, where a HLT (halt) instruction saves significant amounts of power and heat, the idle task almost always consists of a loop which repeatedly executes HLT instructions.
Most operating systems will display an idle task, which is a special task loaded by the OS scheduler only when there is nothing for the computer to do. The idle task can be hard-coded into the scheduler, or it can be implemented as a separate task with the lowest possible priority. An advantage of the latter approach is that programs monitoring the system status can see the idle task along with all other tasks; an example is Windows NT's System idle process. )
On shutdown, Init is called to close down all user space functionality in a controlled manner, again via scripted directions, following which Init terminates and the Kernel executes its own shutdown.
Early user space has been available since version 2.5.46 of the Linux kernel[1], with the intent to replace as many functions as possible that previously the kernel would have performed during the start-up process. Typical uses of early user space are to detect what device drivers are needed to load the main user space file system and load them from a temporary filesystem.
The boot loader phase varies by platform. Since the earlier phases are not specific to the OS, the boot process is considered to start:
From that point, the boot process continues as follows:
The first stage boot loader (in the MBR or the volume boot record) loads the remainder of the boot loader, which typically gives a prompt asking which operating system (or type of session) the user wishes to initialize. LILO and GRUB differ in some ways:[2]
lilo
, reads the configuration file /etc/lilo.conf
to identify the available bootable systems (it is executed from a running Linux system). The configuration file can include data such as boot partition and kernel pathname for each, as well as customized options if needed. To be precise, /etc/lilo.conf
is prior-parsed and used to create fixed-offset information saved in the boot sector and the map file, which will be used at the next boot. This information is discovered by asking the Linux kernel, at map installer time, where (e.g. on which disk sectors) the object of interest (such as an initrd, a kernel image file, or the like) is stored. At boot time, the default or selected operating system is loaded into RAM, a minimal initial file system is possibly set up in RAM from an image file ("initrd"), and along with the appropriate parameters, control is passed to the newly loaded kernel. LILO does not "understand" file systems, so it uses raw disk offsets and the BIOS to load any needed code or data based on data in the boot sector and map file. It cannot "find" /etc/lilo.conf
at boot time because it does not understand file systems; instead it searches fixed locations on the disk memorized the last time the LILO map installer (lilo) was run to generate new offsets in the boot sector and the map file image. Boot time LILO logic loads the menu code, and then, depending on the lilo.conf
directives used to make the map file, along with any user interaction, loads either the boot sector for another system such as Microsoft Windows, or the kernel image for Linux.[2]GRUB supports both direct and chain-loading boot methods, LBA, ext2, ext3, ext4 and "a true command-based, pre-OS environment on x86 machines". It contains three interfaces: a selection menu, a configurot loader (second stage). If the second stage is on a large drive, sometimes an intermediate 1.5 stage is loaded, which contains extra code to allow cylinders above 1024, or LBA type drives, to be read. The 1.5 boot loader is stored (if needed) in the MBR or the boot partition. GRUB does this by storing disk location information (cylinder/head/sector addresses, sector numbers, etc.) inside itself, starting within the boot sector itself. This is a lot like the LILO map installer (see elsewhereAT, ext2, etc.), so GRUB can load any arbitrary file at boot time, including its configuration file, a kernel, an initrd, or in this article). The key difference is the code which is loaded is able to interpret the structure of several filesysation editor, and a command line console.[5]
LILO, the older of the two boot loaders, is almost identical to GRUB in process, except that its command line interface allows only selection of options previously recorded in the boot sector and map file. Thus all changes must be made to its configuration and written to the boot sector and map file, and then the system restarted. An error in configuration can therefore leave a disk unable to be booted without use of a separate boot device (floppy disk etc.) containing a program capable of fixing this.[4] Additionally, it does not understand filesystems. Instead, locations of image files are stored within the boot sector and map file directly[4] and the BIOS is used to access them directly.
Yet another way to boot Linux is from DOS or Windows 9x, where the Linux kernel completely replaces the running copy of this operating system. This can be useful in the case of hardware which needs to be switched on via software and for which such configuration programs are only available for DOS, whereas not for Linux, those being proprietary to the manufacturer and kept an industry secret. This tedious booting method is less necessary nowadays, as Linux has drivers for a multitude of hardware devices, but it has seen some use in mobile devices.
Another case is when the Linux is located on a storage device which is not available to the BIOS for booting: DOS or Windows can load the appropriate drivers to make up for the BIOS limitation, and boot Linux from there.
The kernel in Linux handles all operating system processes, such as memory management, task scheduling, I/O, interprocess communication, and overall system control. This is loaded in two stages - in the first stage the kernel (as a compressed image file) is loaded into memory and decompressed, and a few fundamental functions such as basic memory management are set up. Control is then switched one final time to the main kernel start process. Once the kernel is fully operational – and as part of its startup, upon being loaded and executing – the kernel looks for an init process to run, which (separately) sets up a user space and the processes needed for a user environment and ultimate login. The kernel itself is then allowed to go idle, subject to calls from other processes.
The kernel as loaded is typically an image file, compressed into either zImage or bzImage formats with zlib. A routine at the head of it does a minimal amount of hardware setup, decompresses the image fully into high memory, and takes note of any RAM disk if configured.[6] It then executes kernel startup via ./arch/i386/boot/head
and the startup_32 ()
(for x86 based processors) process.
The startup function for the kernel (also called the swapper or process 0) establishes memory management (paging tables and memory paging), detects the type of CPU and any additional functionality such as floating point capabilities, and then switches to non-architecture specific Linux kernel functionality via a call to start_kernel ()
.
start_kernel executes a wide range of initialization functions. It sets up interrupt handling (IRQs), further configures memory, starts the Init process (the first user-space process), and then starts the idle task via cpu_idle ()
. Notably, the kernel startup process also mounts the initial RAM disk ("initrd") that was loaded previously as the temporary root filing system during the boot phase. This allows driver modules to be loaded without reliance upon other physical devices and drivers, and keeps the kernel smaller. The root file system is later switched via a call to pivot_root ()
which unmounts the temporary root file system and replaces it with the use of the real one, once the latter is accessible. The memory used by the temporary root file system is then reclaimed.
Thus, the kernel initializes devices, mounts the root filesystem specified by the boot loader as read only, and runs Init (/sbin/init
) which is designated as the first process run by the system (PID = 1).[2] A message is printed by the kernel upon mounting the file system, and by Init upon starting the Init process. It may also optionally run Initrd to allow setup and device related matters (RAM disk or similar) to be handled before the root file system is mounted.[2]
According to Red Hat, the detailed kernel process at this stage is therefore summarized as follows:[3]
At this point, with interrupts enabled, the scheduler can take control of the overall management of the system, to provide pre-emptive multi-tasking, and the init process is left to continue booting the user environment in user space.
Init is the father of all processes. Its primary role is to create processes from a script stored in the file/etc/inittab
. This file usually has entries which cause init to spawn gettys on each line that users can log in. It also controls autonomous processes required by any particular system. A run level is a software configuration of the system which allows only a selected group of processes to exist. The processes spawned by init for each of these run levels are defined in the /etc/inittab file.— manual page for Init[7]
Init's job is "to get everything running the way it should be"[8] once the kernel is fully running. Essentially it establishes and operates the entire user space. This includes checking and mounting file systems, starting up necessary user services, and ultimately switching to a user-environment when system startup is completed. It is similar to the Unix and BSD init processes, from which it derived, but in some cases has diverged or became customized. In a standard Linux system, Init is executed with a parameter, known as a runlevel, that takes a value from 1 to 6, and that determines which subsystems are to be made operational. Each runlevel has its own scripts which codify the various processes involved in setting up or leaving the given runlevel, and it is these scripts which are referenced as necessary in the boot process. Init scripts are typically held in directories with names such as "/etc/rc..."
. The top level configuration file for init is at /etc/inittab
.[8]
During system boot, it checks whether a default runlevel is specified in /etc/inittab, and requests the runlevel to enter via the system console if not. It then proceeds to run all the relevant boot scripts for the given runlevel, including loading modules, checking the integrity of the root file system (which was mounted read-only) and then remounting it for full read-write access, and sets up the network.[2]
After it has spawned all of the processes specified, init goes dormant, and waits for one of three events to happen:- processes it started to end or die, a power failure signal, or a request via /sbin/telinit
to further change the runlevel.[7]
This applies to SysV-style init. Other init binaries, such as systemd or Upstart, may behave differently.
|